/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.adama.service;

import fr.adama.dto.AdherentDTO;
import fr.adama.dto.ContratDTO;
import fr.adama.dto.EmployeDTO;
import fr.adama.entite.Adherent;
import fr.adama.entite.Contrat;
import fr.adama.entite.Employe;
import fr.adama.entite.typePerso.EtatContrat;
import fr.adama.exception.ImportEntityException;
import fr.adama.util.DateFormatFactory;
import java.text.SimpleDateFormat;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.hibernate.exception.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author avisto
 */
@Service
@Transactional()
public class ImportEntityFromFileService {

   
    @Autowired
    AdherentService adherentService;
    @Autowired
    EmployeService employeService;
    @Autowired
    ContratService contratService;
    private static final Logger logger = LoggerFactory.getLogger(ImportEntityFromFileService.class);

    /**
     *
     * @param adherent
     * @param employe
     * @param contrat
     * @param nomFichier
     * @throws ImportEntityException
     */
    @Transactional(rollbackFor = ImportEntityException.class)

    public void addEntity(AdherentDTO adherent, EmployeDTO employe, ContratDTO contrat, String nomFichier) throws ImportEntityException {
        //Je valide mon adherent
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<AdherentDTO>> constraintViolationsAdherent
                = validator.validate(adherent);

        if (constraintViolationsAdherent.size() > 0) {

            logger.error("Impossible de valider l'adherent du  fichier {}", nomFichier);
            String error = "";
            for (ConstraintViolation<AdherentDTO> contraintes : constraintViolationsAdherent) {

                logger.error(contraintes.getRootBeanClass().getSimpleName()
                        + "." + contraintes.getPropertyPath() + " " + contraintes.getMessage());
                error = error + "\n" + contraintes.getRootBeanClass().getSimpleName()
                        + "." + contraintes.getPropertyPath() + " " + contraintes.getMessage();
            }
            throw new ImportEntityException(error);

        } else {
            //Mon adherent n'a pas de probleme je cherche s'il existe
            AdherentDTO adherentSearch;
            adherentSearch = adherentService.findByNomPrenom(adherent.getNomPrenom());
            if (adherentSearch == null) {
               Long adherentId = adherentService.add(adherent, Adherent.class);
               adherent.setId(adherentId);
            } else {
                adherent = adherentSearch;
            }

        }

        //Je valide mon employe
        factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
        Set<ConstraintViolation<EmployeDTO>> constraintViolationsEpmloye
                = validator.validate(employe);

        if (constraintViolationsEpmloye.size() > 0) {

            logger.error("Impossible de valider l'adherent du  fichier {}", nomFichier);

            String error = "";
            for (ConstraintViolation<EmployeDTO> contraintes : constraintViolationsEpmloye) {

                logger.error(contraintes.getRootBeanClass().getSimpleName()
                        + "." + contraintes.getPropertyPath() + " " + contraintes.getMessage());
                error = error + "\n" + contraintes.getRootBeanClass().getSimpleName()
                        + "." + contraintes.getPropertyPath() + " " + contraintes.getMessage();
            }
            throw new ImportEntityException(error);
        } else {
            //Mon adherent n'a pas de probleme je cherche s'il existe
            EmployeDTO employeSearch;
            employeSearch = employeService.findByNomPrenom(employe.getNom(), employe.getPrenom());
            if (employeSearch == null) {
             Long  employeId = employeService.add(employe, Employe.class);
             employe.setId(employeId);
            } else {
                employe = employeSearch;
            }

        }

        contrat.setEmploye(employe);
        contrat.setAdherent(adherent);
        contrat.setEtatContrat(EtatContrat.actif);
        try {
            contratService.add(contrat, Contrat.class);
        } catch (DataIntegrityViolationException ex) {
            if (ex.getCause() instanceof ConstraintViolationException) {
                ConstraintViolationException cdts = (ConstraintViolationException) ex.getCause();
                if (cdts.getConstraintName().equalsIgnoreCase("CONTRATADHERENTEMPLOYEEXISTE")) {
                    String error = "Un contrat existe déjà pour l'adherent" + adherent.getNomPrenom() + " et l'employé " + employe.getNom() + " "
                            + employe.getPrenom() + " pour la date " + DateFormatFactory.getDateFormatContrat().format(contrat.getDateEntree());
                    logger.error(error);
                    throw new ImportEntityException(error);
                }
            }
        }

    }

}
